﻿/*
   Author: Tomer Paz
   BOGO.com
   2008
*/

/* the DB client system */

/* the DBClient system is based on AMF3 and relies on web server to use AMFPHP (>=2.0!!) */

package monopoly.DBA {
	import flash.display.Sprite;
	import flash.net.ObjectEncoding;
	import monopoly.DBA.PHPRemoting.*;
	import monopoly.DBA.IDBClient;
	import flash.events.Event;
	import flash.events.EventDispatcher;

	
	public class DBClient extends EventDispatcher implements IDBClient
		{
		// singleton
		private static var _instance:DBClient;
		//AMF gateway
		private var _gateway:String = "http://b-o-g-o.com/amfphp/gateway.php";
		private static const _Procedure:String = "FlashClientProcedures.";
		// PHPRemote object
		private var _p:Remoting;
		// RPC map
		private var _RPC_map:Object;
		// respone arrays
		private var _GameData:Array;
		private var _PlayersData:Array;		//holds Minimal players data per game - by UID
		private var _PropertiesList:Array;
		private var _UserInfo:Array;		// full info for player - by UID

		
		public function DBClient(parameter:SingletonEnforcer):void
			{
			}
			
		/* real constructor. Args: HostName = Web server host name for AMFPHP */
		public static function getInstance(HostName:String, RootSprite:Sprite):DBClient
			{
	        if(_instance == null) 
				{
	            _instance = new DBClient(new SingletonEnforcer());
		
				// AMF3 is our desired protocol version BUT AMFPHP does not support it before v2.0 :(
				//	_instance.objectEncoding = ObjectEncoding.AMF0;

				_instance.init_RPC_map();
				
				// Gateway.php url for NetConnection
				_instance._gateway = "http://" + HostName + "/amfphp/gateway.php";
				
				// get PHPRemoting instance to work with
				_instance._p = Remoting.getInstance(RootSprite.root,_instance._gateway);
				}
			return _instance;
			}
		
		// mapper of RPC Response functions
		
		private function init_RPC_map():void
			{
			_instance._RPC_map = new Object( );
			_instance._RPC_map[ "get_game_data"			] = _instance.get_game_data_response;
			_instance._RPC_map[ "get_players_data"		] = _instance.get_players_data_response;
			_instance._RPC_map[ "get_properties_list"	] = _instance.get_properties_list_response;
			_instance._RPC_map[ "get_player_by_name"	] = _instance.get_player_by_name;
			}
		
		public function get_game_data(gameId:int):void 
			{
			var Procedure:String = _Procedure + "get_game_data";
			var MySQLCall:PHPCall= new PHPCall(Remoting.PHP, this.get_game_data_response, Procedure, gameId);
			}
		public function get_players_data(gameId:int):void
			{
			var Procedure:String = _Procedure + "get_players_data";
			var MySQLCall:PHPCall= new PHPCall(Remoting.PHP, this.get_players_data_response, Procedure, gameId);
			}
		
        public function get_properties_list(gameId:int):void
			{
			var Procedure:String = _Procedure + "get_properties_list";
			var MySQLCall:PHPCall= new PHPCall(Remoting.PHP, this.get_properties_list_response, Procedure, gameId);
			}
		public function get_player_by_name(pname:String):void
			{
			var Procedure:String = _Procedure + "get_player_by_name";
			var MySQLCall:PHPCall= new PHPCall(Remoting.PHP, this.get_player_by_name_response, Procedure, pname);
			}
		
		public function get game_data():Array
			{
			return _instance._GameData;
			}
		
		public function player_data(uid:int):Array
			{
			for (var i = 0; i < _instance._PlayersData.length; i++)
				{
				if (_instance._PlayersData[i].user_id == uid)
					break;
				}
			return _instance._PlayersData[i];
			}
		public function get players_data():Array
			{
			// just return the players data array
			return _instance._PlayersData;
			}
			
		public function get properties_list():Array
			{
			return _instance._PropertiesList;
			}
		
		public function player_by_name():Array
			{
			return _instance._UserInfo;
			}
			
		/* private functions */	
		
		private function get_game_data_response(re:PHPResult):void
			{
			//trace (re.result);
			_instance._GameData = re.result as Array;
			dispatchEvent(new Event(Event.COMPLETE));
			}
		private function get_players_data_response(re:PHPResult):void
			{
			//trace (re.result);
			
			if (null == _instance._PlayersData)
				_instance._PlayersData = new Array();
			_instance._PlayersData = re.result as Array;
			dispatchEvent(new Event(Event.COMPLETE));
			}
        
        private function get_properties_list_response(re:PHPResult):void
			{
			//trace ((re.result as Array)[0]);
			if (null == _instance._PropertiesList)
				_instance._PropertiesList = new Array();
			_instance._PropertiesList = re.result as Array;	// array of associative arrays
			dispatchEvent(new Event(Event.COMPLETE));
			}
		
		private function get_player_by_name_response(re:PHPResult):void
			{
			//trace ((re.result as Array)[0]);
			if (null == _instance._UserInfo)
				_instance._UserInfo = new Array();
			_instance._UserInfo = re.result as Array;
			dispatchEvent(new Event(Event.COMPLETE));
			}
		
		/* a Generic function */
		
		public function CallStoredProcedure(StoreProcedure:String, ... args):void
			{
			var Procedure:String = _Procedure + StoreProcedure;
			var MySQLCall:PHPCall= new PHPCall(Remoting.PHP, this._RPC_map[StoreProcedure], Procedure, args);
			}
		}
}
class SingletonEnforcer {}